/*
 * Copyright (c) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { HvigorNode, HvigorPlugin } from '@ohos/hvigor';
import { OhosPluginId } from '@ohos/hvigor-ohos-plugin';
import { PluginConstants } from './hmrouter_extension/constants';
import { HMRouterPluginManager } from './HMRouterPluginManager';
import { PluginExtension } from './framework';
import { PluginError } from "./hmrouter_extension/error/PluginError";

// Export core components from the framework
export * from './framework/utils';
export * from './framework/extension';

/**
 * Configuration options for HMRouter plugins
 *
 * @interface PluginParam
 * @property {PluginExtension[]} [extensions] - Optional array of custom plugin extensions
 */
export interface PluginParam {
  extensions?: PluginExtension[];
}

export interface AppPluginParam {
  ignoreModuleNames: string[];
}

/**
 * Create a HAP (Harmony Ability Package) plugin instance
 *
 * This function creates a plugin that can be used in Harmony Ability Package modules
 * to analyze and process router annotations.
 *
 * @param {PluginParam} options - Plugin configuration options
 * @returns {HvigorPlugin} The configured HAP plugin instance
 *
 * @example
 * // In hvigorfile.ts of a HAP module
 * import { hapPlugin } from '@hadss/hmrouter-plugin';
 *
 * export default {
 *   system: hapTasks,
 *   plugins: [hapPlugin()]
 * }
 */
export function hapPlugin(options: PluginParam = {}): HvigorPlugin {
  return {
    pluginId: PluginConstants.HAP_PLUGIN_ID,
    apply(node: HvigorNode) {
      HMRouterPluginManager.getInstance().registerPlugin(node, OhosPluginId.OHOS_HAP_PLUGIN, options);
    },
  };
}

/**
 * Create an HSP (Harmony Shared Package) plugin instance
 *
 * This function creates a plugin that can be used in Harmony Shared Package modules
 * to analyze and process router annotations.
 *
 * @param {PluginParam} options - Plugin configuration options
 * @returns {HvigorPlugin} The configured HSP plugin instance
 *
 * @example
 * // In hvigorfile.ts of an HSP module
 * import { hspPlugin } from '@hadss/hmrouter-plugin';
 *
 * export default {
 *   system: hspTasks,
 *   plugins: [hspPlugin()]
 * }
 */
export function hspPlugin(options: PluginParam = {}): HvigorPlugin {
  return {
    pluginId: PluginConstants.HSP_PLUGIN_ID,
    apply(node: HvigorNode) {
      HMRouterPluginManager.getInstance().registerPlugin(node, OhosPluginId.OHOS_HSP_PLUGIN, options);
    },
  };
}

/**
 * Create a HAR (Harmony Archive) plugin instance
 *
 * This function creates a plugin that can be used in Harmony Archive modules
 * to analyze and process router annotations.
 *
 * @param {PluginParam} options - Plugin configuration options
 * @returns {HvigorPlugin} The configured HAR plugin instance
 *
 * @example
 * // In hvigorfile.ts of a HAR module
 * import { harPlugin } from '@hadss/hmrouter-plugin';
 *
 * export default {
 *   system: harTasks,
 *   plugins: [harPlugin()]
 * }
 */
export function harPlugin(options: PluginParam = {}): HvigorPlugin {
  return {
    pluginId: PluginConstants.HAR_PLUGIN_ID,
    apply(node: HvigorNode) {
      HMRouterPluginManager.getInstance().registerPlugin(node, OhosPluginId.OHOS_HAR_PLUGIN, options);
    },
  };
}

export function modulePlugin(options: PluginParam = {}): HvigorPlugin {
  return {
    pluginId: PluginConstants.HAP_PLUGIN_ID,
    apply(node: HvigorNode) {
      node.getAllPluginIds().forEach((pluginId) => {
        HMRouterPluginManager.getInstance().registerPlugin(node, pluginId, options);
      });
    },
  };
}

export function appPlugin(options: AppPluginParam): HvigorPlugin {
  return {
    pluginId: PluginConstants.HAP_PLUGIN_ID,
    apply(node: HvigorNode) {
      if (!options) {
        throw new Error('No options provided');
      }
      node.subNodes(subNode => {
        if (options.ignoreModuleNames.includes(subNode.getNodeName())) {
          return;
        }
        HMRouterPluginManager.getInstance().addModuleNode(subNode)
      })
    },
  };
}
